#include "StdAfx.h"
#include "StreamReceiver.h"

StreamReceiverImpl::StreamReceiverImpl()
{
}

StreamReceiverImpl::~StreamReceiverImpl(void)
{
}

ULONG STDMETHODCALLTYPE StreamReceiverImpl::AddRef( void){return ++refCount;}

ULONG STDMETHODCALLTYPE StreamReceiverImpl::Release( void){return --refCount;}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::QueryInterface( 
    /* [in] */ REFIID riid,
	/* [iid_is][out] */ __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
{
	*ppvObject = this;
	AddRef();
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::SetBaseStream( 
    IStream *pStream,
    REFGUID rguidFormat,
    const WAVEFORMATEX *pWaveFormatEx)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::GetBaseStream( 
    IStream **ppStream)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::BindToFile( 
    /*  */ 
    __in_z  LPCWSTR pszFileName,
    SPFILEMODE eMode,
    /*  */ 
    __in_opt  const GUID *pFormatId,
    /*  */ 
    __in_opt  const WAVEFORMATEX *pWaveFormatEx,
    ULONGLONG ullEventInterest)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Close( void)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::GetFormat( 
    __RPC__in GUID *pguidFormatId,
    __RPC__deref_in_opt WAVEFORMATEX **ppCoMemWaveFormatEx)
{
	int size = sizeof(WAVEFORMATEX);
	LPVOID pVoid = CoTaskMemAlloc(size);
	*ppCoMemWaveFormatEx = (WAVEFORMATEX*)pVoid;
	(*ppCoMemWaveFormatEx)->cbSize = cachedWaveFormat->cbSize;
	(*ppCoMemWaveFormatEx)->nAvgBytesPerSec = cachedWaveFormat->nAvgBytesPerSec;
	(*ppCoMemWaveFormatEx)->nBlockAlign = cachedWaveFormat->nBlockAlign;
	(*ppCoMemWaveFormatEx)->nChannels = cachedWaveFormat->nChannels;
	(*ppCoMemWaveFormatEx)->nSamplesPerSec = cachedWaveFormat->nSamplesPerSec;
	(*ppCoMemWaveFormatEx)->wBitsPerSample = cachedWaveFormat->wBitsPerSample;
	(*ppCoMemWaveFormatEx)->wFormatTag = cachedWaveFormat->wFormatTag;
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Seek( 
        /* [in] */ LARGE_INTEGER dlibMove,
        /* [in] */ DWORD dwOrigin,
        /* [out] */ ULARGE_INTEGER *plibNewPosition)
{
	return S_OK;
}
    
HRESULT STDMETHODCALLTYPE StreamReceiverImpl::SetSize( 
    /* [in] */ ULARGE_INTEGER libNewSize)
{
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiverImpl::CopyTo( 
    /* [unique][in] */ IStream *pstm,
    /* [in] */ ULARGE_INTEGER cb,
    /* [out] */ ULARGE_INTEGER *pcbRead,
    /* [out] */ ULARGE_INTEGER *pcbWritten)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Commit( 
    /* [in] */ DWORD grfCommitFlags)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Revert( void)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::LockRegion( 
    /* [in] */ ULARGE_INTEGER libOffset,
    /* [in] */ ULARGE_INTEGER cb,
    /* [in] */ DWORD dwLockType)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::UnlockRegion( 
    /* [in] */ ULARGE_INTEGER libOffset,
    /* [in] */ ULARGE_INTEGER cb,
    /* [in] */ DWORD dwLockType)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Stat( 
    /* [out] */ __RPC__out STATSTG *pstatstg,
    /* [in] */ DWORD grfStatFlag)
{
	return S_OK;
}

HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Clone( 
    /* [out] */ __RPC__deref_out_opt IStream **ppstm)
{
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Read( 
    /* [length_is][size_is][out] */ void *pv,
    /* [in] */ ULONG cb,
    /* [out] */ ULONG *pcbRead)
{
	return S_OK;
}

/* [local] */ HRESULT STDMETHODCALLTYPE StreamReceiverImpl::Write( 
    /* [size_is][in] */ const void *pv,
    /* [in] */ ULONG cb,
    /* [out] */ ULONG *pcbWritten)
{
	int shortSize = cb/2;
	if(samples.size()!=shortSize)
	{
		samples.resize(shortSize);
	}
	short* shortAr = (short*)pv;
	for(int i=0; i<shortSize; i++)
	{
		samples[i] = shortAr[i];
	}
	owner->NewSample(&samples[0], shortSize);
	if(pcbWritten)
		*pcbWritten = cb;
	return S_OK;
}

